package top.wilsonlv.jaguar.cloud.auth.security;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import top.wilsonlv.jaguar.cloud.auth.sdk.AuthSdkConstant;
import top.wilsonlv.jaguar.security.component.JaguarLogoutSuccessHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;

/**
 * @author lvws
 * @since 2021/12/17
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class LogoutSuccessHandler extends JaguarLogoutSuccessHandler {

    private final TokenStore tokenStore;

    private final RedisTemplate<String, Serializable> redisTemplate;

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        super.onLogoutSuccess(request, response, authentication);

        //session主动注销后，官方服务token一并注销
        BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(AuthSdkConstant.OAUTH_CLIENT_CACHE_KEY);
        Set<Object> keys = operations.keys();
        if (!CollectionUtils.isEmpty(keys)) {
            for (Object key : keys) {
                Collection<OAuth2AccessToken> tokens = tokenStore.findTokensByClientIdAndUserName((String) key, authentication.getName());
                for (OAuth2AccessToken token : tokens) {
                    if (token.getRefreshToken() != null) {
                        tokenStore.removeRefreshToken(token.getRefreshToken());
                    }
                    tokenStore.removeAccessToken(token);
                }
            }
        }
    }
}
